package com.hanxiaozhang.system.controller;

import java.util.List;
import java.util.Map;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.hanxiaozhang.redis.util.CacheUtil;
import com.hanxiaozhang.result.Result;
import com.hanxiaozhang.result.ResultCode;
import com.hanxiaozhang.security.CurrentUserUtil;
import com.hanxiaozhang.system.dao.UserDao;
import com.hanxiaozhang.system.dto.UserDTO;
import com.hanxiaozhang.util.PageUtil;
import com.hanxiaozhang.validation.util.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.ConcurrentUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.hanxiaozhang.system.entity.UserEntity;
import com.hanxiaozhang.system.service.UserService;

import javax.annotation.Resource;


/**
 * 用户表
 *
 * @author hanxiaozhang
 * @email hanxiaozhang2018@sina.com
 * @date 2021-04-02
 */
@Slf4j
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private ConsumerTokenServices consumerTokenServices;

    @Resource
    private UserDao userDao;

    @Autowired
    private CacheUtil cacheUtil;

    /**
     * 查询列表
     *
     * @param params
     * @return
     */
    @ResponseBody
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('system:user:list')")
    public Result<PageUtil> list(@RequestParam Map<String, Object> params) {

        params.put("offset", (Integer.parseInt(params.get("current").toString()) - 1));
        params.put("limit", Integer.parseInt(params.get("pageSize").toString()));
        params.remove("current");
        params.remove("pageSize");
        List<UserDTO> userList = userService.list(params);
        int total = userDao.count(params);
        return Result.success(new PageUtil(userList, total));
    }


    /**
     * 保存
     *
     * @param user
     * @return
     */
    @ResponseBody
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:save')")
    public Result<Void> save(UserDTO user) {
        valid(user, true);
        userService.save(user);
        return Result.success();
    }


    /**
     * 修改
     *
     * @param user
     * @return
     */
    @ResponseBody
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('system:user:update')")
    public Result<Void> update(UserDTO user) {
        valid(user, false);
        userService.update(user);
        return Result.success();
    }


    /**
     * 重置密码
     *
     * @param params
     * @return
     */
    @ResponseBody
    @PostMapping("/resetPassword")
    @PreAuthorize("hasAuthority('system:user:resetPassword')")
    public Result<Void> resetPassword(@RequestBody Map<String, String> params) {

        String passwordOne = params.get("passwordOne");
        String passwordTwo = params.get("passwordTwo");
        if (!passwordOne.equals(passwordTwo)) {
            return Result.error(10005, "两遍密码不一致");
        }
        Long userId = Long.valueOf(params.get("userId"));
        userService.updatePassword(userId, passwordOne);
        return Result.success();
    }

    /**
     * 参数校验
     *
     * @param user
     * @param saveFlag
     */
    private void valid(UserDTO user, boolean saveFlag) {
        ValidationUtil.checkParameter(ValidationUtil.checkObjectIsNotNull(user.getUsername()), "用户名称不能为空");
        ValidationUtil.checkParameter(!user.getDeptIds().isEmpty(), "部门不能为空");
        ValidationUtil.checkParameter(!user.getRoleIds().isEmpty(), "角色不能为空");
        ValidationUtil.checkParameter(!user.getJobIds().isEmpty(), "岗位不能为空");
        ValidationUtil.checkParameter(ValidationUtil.checkObjectIsNotNull(user.getName()), "姓名不能为空");
        if (saveFlag) {
            UserDTO oldUser = userDao.getByUsername(user.getUsername());
            ValidationUtil.checkParameter(oldUser == null, "用户名称重复");
        } else {
            UserEntity oldUser = userDao.getByUsernameAndNoUserId(user.getUsername(), user.getUserId());
            ValidationUtil.checkParameter(oldUser == null, "用户名称重复");
        }
    }


    /**
     * 删除
     *
     * @param userId
     * @return
     */
    @PostMapping("/remove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:user:remove')")
    public Result<Void> remove(Long userId) {

        return userService.remove(userId);
    }


    /**
     * 批量删除
     *
     * @param userIds
     * @return
     */
    @PostMapping("/batchRemove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:user:batchRemove')")
    public Result<Void> batchRemove(Long[] userIds) {

        return userService.batchRemove(userIds);
    }


    /**
     * 用户自己更像信息
     *
     * @param user
     * @return
     */
    @ResponseBody
    @PostMapping("/updateUser")
    public Result<Void> updateUser(UserDTO user) {

        userService.updateUser(user);
        return Result.success();
    }


    /**
     * 用户修改密码
     *
     * @param params
     * @return
     */
    @ResponseBody
    @PostMapping("/updatePassword")
    public Result<Void> updatePassword(@RequestBody Map<String, String> params, @RequestHeader("Authorization") String authorization) {

        Long userId = CurrentUserUtil.getUserId();
        UserDTO user = userDao.get(userId);
        String oldPassword = params.get("oldPassword");
        if (!new BCryptPasswordEncoder().matches(oldPassword, user.getPassword())) {
            return Result.error(10005, "原始密码错误");
        }
        String passwordOne = params.get("passwordOne");
        String passwordTwo = params.get("passwordTwo");
        if (!passwordOne.equals(passwordTwo)) {
            return Result.error(10005, "两遍密码不一致");
        }
        userService.updatePassword(userId, passwordOne);

        String[] tokenArray = authorization.split(" ");

        if (consumerTokenServices.revokeToken(tokenArray[1])) {
            cacheUtil.delRouterAndCurUserByUserId(userId);
        } else {
            return Result.error(ResultCode.USER_LOGOUT_ERROR);
        }

        return Result.success();
    }


}
